package cn.jx.cjm.common.aop.advice;

import cn.jx.cjm.common.aop.annotation.RequestModel;
import cn.jx.cjm.common.base.BaseRequest;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.lang.reflect.ParameterizedType;
import java.net.URLDecoder;

/**
 * @author James Chen right_way@foxmail.com
 * @since 2020/9/25 5:54 下午
 */
@Slf4j
public class RequestModelArgumentResolver implements HandlerMethodArgumentResolver {

    private final static String REQUEST_PARAM_NAME = "request";
    private final static String CHARSET = "UTF-8";



    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(BaseRequest.class) && parameter.hasParameterAnnotation(RequestModel.class);
    }

    @Override
    public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        String request = webRequest.getParameter(REQUEST_PARAM_NAME);
        BaseRequest<?> baseRequest;

        if (StringUtils.isEmpty(request)) {
            baseRequest = new BaseRequest<>();
        } else{
            request = URLDecoder.decode(request, CHARSET);
            baseRequest = JSON.parseObject(request, BaseRequest.class);
        }
        ParameterizedType type = (ParameterizedType) parameter.getGenericParameterType();
        String actualTypeName = type.getActualTypeArguments()[0].getTypeName();
        baseRequest.setClassName(actualTypeName);
        return baseRequest;
    }
}